package edu.hcmus.sow.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.model.AccessControlEntry;
import org.springframework.security.acls.model.MutableAcl;
import org.springframework.security.acls.model.MutableAclService;
import org.springframework.security.acls.model.NotFoundException;
import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.security.acls.model.Permission;
import org.springframework.security.acls.model.Sid;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import edu.hcmus.sow.domain.Repository;

@Service
@Transactional
public class SecurityService {

   @Autowired
   private MutableAclService aclService;

   // @PreAuthorize("hasPermission(#repository, admin)")
   public void addPermission(Repository repository, Sid recipient, Permission permission) {
      MutableAcl acl;
      ObjectIdentity oid = new ObjectIdentityImpl(Repository.class, repository.getId());

      try {
         acl = (MutableAcl) aclService.readAclById(oid);
      } catch (NotFoundException nfe) {
         acl = aclService.createAcl(oid);
      }

      acl.insertAce(acl.getEntries().size(), permission, recipient, true);
      aclService.updateAcl(acl);

   }

   @PreAuthorize("hasPermission(#repository, admin)")
   public void deletePermission(Repository repository, Sid recipient, Permission permission) {
      ObjectIdentity oid = new ObjectIdentityImpl(Repository.class, repository.getId());
      MutableAcl acl = (MutableAcl) aclService.readAclById(oid);

      // Remove all permissions associated with this particular recipient (string equality to KISS)
      List<AccessControlEntry> entries = acl.getEntries();

      for (int i = 0; i < entries.size(); i++) {
         if (entries.get(i).getSid().equals(recipient) && entries.get(i).getPermission().equals(permission)) {
            acl.deleteAce(i);
         }
      }

      aclService.updateAcl(acl);

   }
}
